using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using Hiranipra.Scenes.Island;
using System.Diagnostics;
using Hiranipra.Audio;
using Hiranipra.Graphics;
using Hiranipra.Input;
using Hiranipra.SceneModel;
using Hiranipra.Physics;

namespace Hiranipra
{
	/// <summary>
	/// This is the main type for your game
	/// </summary>
	public class GameClient : Microsoft.Xna.Framework.Game
	{
		public GraphicsDeviceManager GraphicsManager;
		public SpriteBatch SpriteBatch;

		private AudioComponent _audioComponent;
		private GraphicsComponent _graphicsComponent;
		private InputComponent _inputComponent;
		private PhysicsComponent _physicsComponent;
		private SceneComponent _sceneComponent;

		public GameClient()
		{
			GraphicsManager = new GraphicsDeviceManager( this );
			this.Content.RootDirectory = "Content";
		}

		/// <summary>
		/// Allows the game to perform any initialization it needs to before starting to run.
		/// This is where it can query for any required services and load any non-graphic
		/// related content.  Calling base.Initialize will enumerate through any components
		/// and initialize them as well.
		/// </summary>
		protected override void Initialize()
		{
			// TODO: Add your initialization logic here

			_audioComponent = new AudioComponent( this );
			_graphicsComponent = new GraphicsComponent( this );
			_inputComponent = new InputComponent( this );
			_physicsComponent = new PhysicsComponent( this );
			_sceneComponent = new SceneComponent( this );

			this.Components.Add( _inputComponent );
			this.Components.Add( _sceneComponent );
			this.Components.Add( _physicsComponent );
			this.Components.Add( _graphicsComponent );
			this.Components.Add( _audioComponent );

			base.Initialize();
		}

		/// <summary>
		/// LoadContent will be called once per game and is the place to load
		/// all of your content.
		/// </summary>
		protected override void LoadContent()
		{
			// Create a new SpriteBatch, which can be used to draw textures.
			SpriteBatch = new SpriteBatch( GraphicsDevice );

			// TODO: use this.Content to load your game content here
		}

		/// <summary>
		/// UnloadContent will be called once per game and is the place to unload
		/// all content.
		/// </summary>
		protected override void UnloadContent()
		{
			// TODO: Unload any non ContentManager content here
		}

		/// <summary>
		/// Allows the game to run logic such as updating the world,
		/// checking for collisions, gathering input, and playing audio.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Update( GameTime gameTime )
		{
			// Allows the game to exit
			if( GamePad.GetState( PlayerIndex.One ).Buttons.Back == ButtonState.Pressed )
				this.Exit();

			// TODO: Add your update logic here

			base.Update( gameTime );
		}

		/// <summary>
		/// This is called when the game should draw itself.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Draw( GameTime gameTime )
		{
			GraphicsManager.GraphicsDevice.Clear( Color.CornflowerBlue );

			// TODO: Add your drawing code here

			base.Draw( gameTime );
		}
	}
}
